home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / util / libs / shutdown.lha / shutdown_5.3 / src / unmount.c < prev   
Encoding:
C/C++ Source or Header  |  1998-09-12  |  4.4 KB  |  219 lines

  1. /*
  2.    unmount.c --- unmount filesystems.
  3.  
  4.    (c) Copyright 1995-98 SHW Wabnitz
  5.    Written by Bernhard Fastenrath (fasten@shw.com)
  6.  
  7.    This file may be distributed under the terms
  8.    of the GNU General Public License.
  9. */
  10.  
  11. #include "shutdown_cmd.h"
  12. #include <stdio.h>
  13.  
  14. typedef struct {
  15.   struct Message   sp_Msg;
  16.   struct DosPacket sp_Pkt;
  17.   struct Node     *sp_Dev;
  18. } MyStandardPacket;
  19.  
  20. /// FreeList()
  21. static void
  22. FreeList (List *list)
  23. {
  24.   Node *node, *next;
  25.  
  26.   for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
  27.   {
  28.     if (node -> ln_Name)
  29.       FreeMem (node -> ln_Name, node -> ln_Pri);
  30.     FreeMem (node, sizeof (Node));
  31.   }
  32. }
  33. ///
  34.  
  35. /// FreeStdPktList()
  36. static void
  37. FreeStdPktList (List *list)
  38. {
  39.   Node *node, *next;
  40.  
  41.   for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
  42.     FreeMem (node, sizeof (MyStandardPacket));
  43. }
  44. ///
  45.  
  46. /// SendStandardPacket()
  47. static int
  48. SendStandardPacket (MsgPort *mp, MyStandardPacket *sp, char *handler, ULONG action, ULONG arg1)
  49. {
  50.   DevProc *dp = NULL;
  51.  
  52.   dp = GetDeviceProc (handler, dp);
  53.   if (dp)
  54.   {
  55.     sp -> sp_Pkt.dp_Type = action;
  56.     sp -> sp_Pkt.dp_Arg1 = arg1;
  57.     SendPkt (&sp -> sp_Pkt, dp -> dvp_Port, mp);
  58.     FreeDeviceProc (dp);
  59.     return 1;
  60.   }
  61.   return 0;
  62. }
  63. ///
  64.  
  65. /// AllocateStandardPackets ()
  66. static int
  67. AllocateStandardPackets (List *pktlist, int count)
  68. {
  69.   MyStandardPacket *sp;  
  70.   int t;
  71.  
  72.   NewList (pktlist);
  73.  
  74.   for (t=0; t<count; t++)
  75.   {
  76.     if (!(sp = AllocMem (sizeof (MyStandardPacket), MEMF_PUBLIC | MEMF_CLEAR)))
  77.       break;
  78.     sp -> sp_Msg.mn_Length = sizeof (MyStandardPacket);
  79.     sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
  80.     sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
  81.     AddTail (pktlist, &sp -> sp_Msg.mn_Node);
  82.   }
  83.   return t;
  84. }
  85. ///
  86.  
  87. /// SendToAll()
  88. static int
  89. SendToAll (MsgPort *mp, ULONG action, ULONG arg1)
  90. {
  91.   int len, count = 0, icount = 0, out_of_mem = 0;
  92.   List devlist, pktlist;
  93.   MyStandardPacket *sp;
  94.   Node *node;
  95.   DosList *dl;
  96.   char *name;
  97.  
  98.   NewList (&devlist);
  99.   NewList (&pktlist);
  100.  
  101.   dl = LockDosList ( LDF_DEVICES | LDF_READ );
  102.  
  103.   while (dl = NextDosEntry (dl, LDF_DEVICES))
  104.   {
  105.     if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
  106.     {
  107.       name = BADDR (dl -> dol_Name);
  108.       len = (int) name[0];
  109.  
  110.       if (node -> ln_Name = AllocMem (len + 2, 0))
  111.       {
  112.         CopyMem (name+1, node -> ln_Name, len);
  113.         node -> ln_Name[len] = ':';
  114.         node -> ln_Name[len+1] = '\0';
  115.         node -> ln_Pri = len + 2;
  116.         AddTail (&devlist, node);
  117.         count ++;
  118.       }
  119.       else
  120.       {
  121.         out_of_mem = 1;
  122.         FreeMem (node, sizeof (Node));
  123.         break;
  124.       }
  125.     }
  126.   }
  127.  
  128.   UnLockDosList ( LDF_DEVICES | LDF_READ );
  129.  
  130.   if ((icount = AllocateStandardPackets (&pktlist, count)) == 0)
  131.     out_of_mem = 1;
  132.   count = icount;
  133.  
  134.   if (out_of_mem)
  135.   {
  136.     FreeStdPktList (&pktlist);
  137.     FreeList (&devlist);
  138.     return 0;
  139.   }
  140.  
  141.   node = devlist.lh_Head;
  142.   for (;;)
  143.   {
  144.     while (node -> ln_Succ)
  145.     {
  146.       if (sp = (MyStandardPacket *) RemHead (&pktlist))
  147.       {
  148.         sp -> sp_Dev = node;
  149.         SendStandardPacket (mp, sp, node -> ln_Name, ACTION_IS_FILESYSTEM, 0);
  150.         icount --;
  151.         node = node -> ln_Succ;
  152.       }
  153.     }
  154.     WaitPort (mp);
  155.  
  156.     while (sp = (MyStandardPacket *) GetMsg (mp))
  157.     {
  158.       icount ++;
  159.  
  160.       if (sp -> sp_Pkt.dp_Type == ACTION_IS_FILESYSTEM &&
  161.           sp -> sp_Pkt.dp_Res1 == DOSTRUE)
  162.       {
  163.         SendStandardPacket (mp, sp, sp -> sp_Dev -> ln_Name, action, arg1);
  164.         icount --;
  165.       }
  166.       else
  167.       {
  168.         AddTail (&pktlist, &sp -> sp_Msg.mn_Node);
  169.       }
  170.     }
  171.     if (!node -> ln_Succ && icount == count)
  172.       break;
  173.   }
  174.   FreeStdPktList (&pktlist);
  175.   FreeList (&devlist);
  176.   return 1;
  177. }
  178. ///
  179.  
  180. /// FsAction()
  181. static int
  182. FsAction (MsgPort *mp, ULONG action, ULONG arg)
  183. {
  184.   return !SendToAll (mp, action, arg);
  185. }
  186. ///
  187.  
  188. /*** public functions ***/
  189.  
  190. /// Unmount()
  191. int
  192. Unmount (char *filesystem, int mode)
  193. {
  194.   MsgPort *mp;
  195.   int status;
  196.  
  197.   if (!(mp = CreatePort (NULL, 0)))
  198.     return 0;
  199.  
  200.   switch (mode)
  201.   {
  202.     case UMNT_INHIBIT:
  203.       status  = FsAction (mp, ACTION_INHIBIT, DOSTRUE);
  204.       break;
  205.     case UMNT_READONLY:
  206.       status  = FsAction (mp, ACTION_FLUSH, DOSTRUE);
  207.       status |= FsAction (mp, ACTION_WRITE_PROTECT, DOSTRUE);
  208.       break;
  209.     case UMNT_REMOUNT:
  210.       /* status  = FsAction (mp, ACTION_WRITE_PROTECT, DOSFALSE); */
  211.       status  = FsAction (mp, ACTION_INHIBIT, DOSTRUE);
  212.       status |= FsAction (mp, ACTION_INHIBIT, DOSFALSE);
  213.       break;
  214.   }
  215.   DeletePort (mp);
  216.   return !status;
  217. }
  218. ///
  219.